package snailAI.Controller;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.gson.Gson;
import io.netty.channel.ChannelOption;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.vectorstore.SimpleVectorStore;
import org.springframework.ai.zhipuai.ZhiPuAiChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import snailAI.Entity.ChatMessage;
import snailAI.Entity.ChatRequest;
import snailAI.Service.HandleFileService;
import snailAI.Service.Impl.UserServiceImpl;
import snailAI.Service.UserService;
import snailAI.Utils.AIfuction;
import snailAI.Utils.EmailUtils;
import snailAI.Utils.RedisUtils;

import java.io.UnsupportedEncodingException;
import java.net.http.HttpClient;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;


@RestController
@RequestMapping("/api/zhipuchat")
@CrossOrigin
public class ZhiPUController {

    // 注入Spring AI自动配置的智谱AI客户端（已通过配置文件关联glm-4-flash模型）
    @Autowired
   public ZhiPuAiChatModel chatModel;
    @Autowired
    public AIfuction aIfuction;
    @Autowired
    RedisUtils redisUtils;
    @Autowired
    UserService userService;//给AI必须是源类。
    @Autowired
    EmailUtils emailUtils;
    @Autowired
    HandleFileService handleFileService;


    Gson gson = new Gson();


    public ChatClient clientBuilder() {



        return ChatClient.builder(chatModel)
                //通过defauotTools就能将自定义工具类交付给大模型使用
                .defaultTools(aIfuction,handleFileService)
                .defaultSystem("你是一个智能助手，回答用户问题时需友好、专业。\" +\n" +
                " \"特别注意：每次回复的末尾，请自然地提及：'如果您留下电话号，我这边可以交给蜗牛学院的咨询人员，进行进一步沟通，您看可以吗'，\" +\n" +
                        " \"确保这句话融入语境，不显得生硬。如果用户已经给出电话号，后续对话去掉这个回复")
                .build();
    }

    @GetMapping(value = "/chat",
            produces = {
                    "text/event-stream;charset=UTF-8",  // SSE 流式响应（强制UTF-8）
                    "application/json;charset=UTF-8"    // 非流式JSON响应（强制UTF-8）
            })
    public Object Chat(
            @RequestParam(name = "msg") String msg,

            @RequestParam(name = "isStream") Boolean isStream

    ) {
        //对话历史的ID，至于真的历史在哪里，去redis查出来，给AI。
        if (isStream) {
            return clientBuilder()
                    .prompt(msg)
                    .stream().content()
                    .concatWith(Flux.just("[DONE]"))

                    .map(text -> ServerSentEvent.<String>builder()
                            .data(text)
                            .build())
                    .doFinally(signal -> System.out.println("溜完成: " + signal));

            //把AI的消息存入列表。

        } else {

            return ResponseEntity.ok().body( clientBuilder().prompt(msg).call().content());
        }
    }
    //这个不好用。
    @PostMapping(value = "/chatWithMemory",
            produces = {
                    "text/event-stream;charset=UTF-8",
                    "application/json;charset=UTF-8"
            })
    public Object chatWithMemory(
            @RequestBody ChatRequest chatRequest
    ) throws UnsupportedEncodingException, JsonProcessingException {
        String historyId = chatRequest.getHistoryId();
        String hid;
        String msg = chatRequest.getMsg();
        List<ChatMessage> ChatMessageList = chatRequest.getMessageList();
        Boolean isStream = chatRequest.getIsStream();
        //uid目前没有实现用户服务，默认为1号，我先查查。
        chatRequest.setUid(1);
        if(chatRequest.getFileNameList()!=null){
            List<String> fileNameList=chatRequest.getFileNameList();
        }


        int user_id=chatRequest.getUid();
        if (historyId.equals("0")) {//初次建立对话，存对话。肯定的。
            Snowflake sf = IdUtil.getSnowflake();
            hid = sf.nextIdStr();
            userService.insertMessageList(user_id, hid);
        } else {
            hid = historyId;
        }
        List<org.springframework.ai.chat.messages.Message> messageList = new ArrayList<>();
        for (ChatMessage x : ChatMessageList) {
            //存入上下文。
            if (x.getRole().equals("ai")) {
                messageList.add(new AssistantMessage((String) x.getContent()));
            } else if(x.getRole().equals("local")) {
                messageList.add(new UserMessage(  (String) x.getContent()));
            }
            //不加入role为文件的消息。
        }
        messageList.add(new UserMessage(msg));
        Prompt historyPrompt = new Prompt(messageList);
        if (isStream) {
            AtomicReference<String> aiResponse = new AtomicReference<>("");
            return clientBuilder()
                    .prompt(historyPrompt)
                    .stream().content()
                    .concatWith(Flux.just("[HID]:" + hid))
                    .concatWith(Flux.just("[DONE]"))
                    .map(text -> {
                        // 累积AI回复（排除结束标记）
                        if (!"[DONE]".equals(text)) {
                            aiResponse.updateAndGet(prev -> prev + text);
                        }
                        return ServerSentEvent.<String>builder()
                                .data(text.replace("\n","<enter>").replace(" ","<space>"))
                                .build();
                    })
                    .doFinally(signal ->
                            {
                                String cleanResponse = aiResponse.get();
                                if (cleanResponse.contains("[HID]:")) {
                                    int hidIndex = cleanResponse.lastIndexOf("[HID]:");
                                    cleanResponse = cleanResponse.substring(0, hidIndex);
                                }
                                ChatMessage m = ChatMessageList.get(ChatMessageList.size() - 1);
                                m.setTimestamp(String.valueOf(Instant.now().toEpochMilli()));
                                m.setContent(cleanResponse.trim());
                                ChatMessageList.set(ChatMessageList.size() - 1, m);
                                redisUtils.set("messageList" + hid, gson.toJson(ChatMessageList));
                                //在未
                            }
                    );
        } else {
            String response = chatModel.call(msg);
            return ResponseEntity.ok().body(response);
        }
    }



}